//
//  DPRunLoopSource.m
//  UITestingKit
//
//  Created by Ofri Wolfus on 09/02/07.
//  Copyright 2007 Ofri Wolfus. All rights reserved.
//

#import "DPRunLoopSource.h"


@implementation DPRunLoopSource

static void _DPSchedule(void *info, CFRunLoopRef rl, CFStringRef mode) {
	[(DPRunLoopSource *)info scheduleWithRunLoop:rl forMode:(NSString *)mode];
}

static void _DPCancel(void *info, CFRunLoopRef rl, CFStringRef mode) {
	[(DPRunLoopSource *)info cancelMode:(NSString *)mode forRunLoop:rl];
}

static void _DPPerform(void *info) {
	[(DPRunLoopSource *)info fire];
}

- (id)init {
	if ((self = [super init])) {
		CFRunLoopSourceContext cont = {
			0,					// version
			self,				// info
			NULL,				// retain
			NULL,				// release
			/* the following 3 functions work fine with
			   ObjC objects, thanks to toll-free bridging */
			CFCopyDescription,	// copy description
			CFEqual,			// equal
			CFHash,				// hash
			_DPSchedule,		// schedule
			_DPCancel,			// cancel
			_DPPerform			// perform
		};
		
		_src = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &cont);
	}
	
	return self;
}

- (void)dealloc {
	[self invalidate];
	CFRelease(_src); _src = NULL;
	[super dealloc];
}

- (void)fire {
}

- (void)signal {
	CFRunLoopSourceSignal(_src);
}

- (void)invalidate {
	CFRunLoopSourceInvalidate(_src);
}

- (BOOL)isValid {
	return CFRunLoopSourceIsValid(_src);
}

- (void)scheduleWithRunLoop:(CFRunLoopRef)rl forMode:(NSString *)mode {
}

- (void)cancelMode:(NSString *)mode forRunLoop:(CFRunLoopRef)rl {
}

- (CFRunLoopSourceRef)getCFRunLoopSource {
	return _src;
}

@end


@implementation NSRunLoop (DPRunLoopSource)

- (void)addSource:(DPRunLoopSource *)src forMode:(NSString *)mode {
	CFRunLoopAddSource([self getCFRunLoop], [src getCFRunLoopSource], (CFStringRef)mode);
}

- (void)removeSource:(DPRunLoopSource *)src forMode:(NSString *)mode {
	CFRunLoopRemoveSource([self getCFRunLoop], [src getCFRunLoopSource], (CFStringRef)mode);
}

- (BOOL)containsSource:(DPRunLoopSource *)src inMode:(NSString *)mode {
	return (BOOL)CFRunLoopContainsSource([self getCFRunLoop], [src getCFRunLoopSource],
										 (CFStringRef)mode);
}

@end
